package com.windward.vii.service;

import com.windward.vii.common.Constants;
import com.windward.vii.common.JsonResult;
import com.windward.vii.common.ResultCode;
import com.windward.vii.dao.entity.*;
import com.windward.vii.dao.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import java.util.Date;

/**
 * Created by tiansj on 2017/8/29.
 */
@Component
public class RedPacketService {

    @Autowired
    PlatformTransactionManager transactionManager;
    @Resource
    ChatMapper chatMapper;
    @Resource
    RedPacketMapper redPacketMapper;
    @Resource
    RedPacketRecordMapper redPacketRecordMapper;
    @Resource
    AssetUserAccountMapper assetUserAccountMapper;
    @Resource
    AssetUserConsumeMapper assetUserConsumeMapper;
    @Resource
    AssetUserIncomeMapper assetUserIncomeMapper;

    public JsonResult getRedPacketList() {
        JsonResult jsonResult = JsonResult.success();
        jsonResult.setBody(redPacketMapper.getRedPacketList());
        return jsonResult;
    }

    public JsonResult sendGift(Long uid, Long anchorUid, Long chatId, Long redPacketId) {
        // 检查聊天关系和状态
        Chat chat = chatMapper.selectByPrimaryKey(chatId);
        if(chat == null) {
            return new JsonResult(ResultCode.ERROR_CODE_701,"聊天关系不存在(chatId错误)，请重试");
        }
        if(!chat.getAnchorUid().equals(anchorUid) || !chat.getUid().equals(uid)) {
            return new JsonResult(ResultCode.ERROR_CODE_701,"聊天关系无法对应");
        }
        if(chat.getStatus() != Constants.Chat.STATUS_ACCEPT) {
            return new JsonResult(ResultCode.ERROR_CODE_701,"聊天状态可能已取消或终止");
        }

        // 检查红包
        RedPacket redPacket = redPacketMapper.selectByPrimaryKey(redPacketId);
        if(redPacket == null) {
            return JsonResult.error("红包已下架，请刷新界面");
        }

        int price = redPacket.getCoin();

        // 检查用户余额
        AssetUserAccount assetUserAccount = assetUserAccountMapper.selectByUid(uid);
        if(assetUserAccount.getAvailableRechargeCoin() + assetUserAccount.getAvailableIncomeCoin() < price) {
            return new JsonResult(ResultCode.ERROR_CODE_702,"可用V钻不足，请充值");
        }

        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = transactionManager.getTransaction(def);
        boolean isConsumeSuccess = false;
        try {
            // 扣除用户的钱
            int row = 0;
            int availableRechargeCoin = assetUserAccount.getAvailableRechargeCoin();
            if(availableRechargeCoin >= price) {
                row = assetUserAccountMapper.consumeRechargeIcon(uid, price);
            } else if(availableRechargeCoin > 0) {
                row = assetUserAccountMapper.consumeRechargeIcon(uid, availableRechargeCoin);
                if(row > 0) {
                    row = assetUserAccountMapper.consumeIncomeIcon(uid, price - availableRechargeCoin);
                }
            } else {
                row = assetUserAccountMapper.consumeIncomeIcon(uid, price);
            }
            if(row <= 0) {
                return new JsonResult(ResultCode.ERROR_CODE_703,"扣除用户V钻失败，请重试");
            }
            // 添加消费记录
            AssetUserConsume assetUserConsume = new AssetUserConsume();
            assetUserConsume.setUid(uid);
            assetUserConsume.setAnchorUid(anchorUid);
            assetUserConsume.setCoin(price);
            assetUserConsume.setChatId(chatId);
            assetUserConsume.setType(Constants.AssetUserConsume.TYPE_RED_PACKET);
            assetUserConsume.setCreateTime(new Date());
            row = assetUserConsumeMapper.insertSelective(assetUserConsume);
            if(row <= 0) {
                return new JsonResult(ResultCode.ERROR_CODE_704,"生成用户消费记录失败，请重试");
            }

            // 增加主播的钱
            row = assetUserAccountMapper.income(anchorUid, price, 1);
            if(row <= 0) {
                return new JsonResult(ResultCode.ERROR_CODE_705,"增加播主收入失败，请重试");
            }
            // 添加收入记录
            AssetUserIncome assetUserIncome = new AssetUserIncome();
            assetUserIncome.setConsumerUid(uid);
            assetUserIncome.setUid(anchorUid);
            assetUserIncome.setCoin(price);
            assetUserIncome.setChatId(chatId);
            assetUserIncome.setType(Constants.AssetUserConsume.TYPE_RED_PACKET);
            assetUserIncome.setCreateTime(new Date());
            row = assetUserIncomeMapper.insertSelective(assetUserIncome);
            if(row <= 0) {
                return new JsonResult(ResultCode.ERROR_CODE_706,"生成播主收入记录，请重试");
            }

            // 添加送礼记录
            RedPacketRecord redPacketRecord = new RedPacketRecord();
            redPacketRecord.setSenderUid(uid);
            redPacketRecord.setReceiverUid(anchorUid);
            redPacketRecord.setChatId(chatId);
            redPacketRecord.setRedPacketId(redPacketId);
            redPacketRecord.setRedPacketCoin(redPacket.getCoin());
            redPacketRecord.setRedPacketName(redPacket.getName());
            redPacketRecord.setCreateTime(new Date());
            row = redPacketRecordMapper.insertSelective(redPacketRecord);
            if(row <= 0) {
                return new JsonResult(ResultCode.ERROR_CODE_704,"生成红包记录失败，请重试");
            }

            isConsumeSuccess = true;
            JsonResult response = JsonResult.success();
            response.setBody(assetUserAccount.getAvailableRechargeCoin() + assetUserAccount.getAvailableIncomeCoin() - price);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error();
        } finally {
            if(isConsumeSuccess) {
                transactionManager.commit(status);
            } else {
                transactionManager.rollback(status);
            }
        }
    }
}
